
use strict;
use warnings;
use Data::Dumper;

my @mystack;

# the last index
my $lindent=1;

# the top level
my $lname="TOP";

my $debug=0;

sub Peek
{
    my $bottom = $mystack[-1];
    if ($bottom)
    {
	my ($cindent,$cval) = @{$bottom};
	print "check1:$cindent| $cval  \n" if $debug;
	return [$cindent,$cval];
    }
    else
    {
	return ["1","MISSING"];
    }
}


sub PrintStack
{
    my $size=$#mystack;

#    print "Stack:" . Dumper(\@mystack) . "\n";

    for (my $x =$size; $x >0 ; $x--)
    {
	my $bottom = $mystack[$x];
	if ($bottom)
	{
	    my ($cindent,$cval) = @{$bottom};
	    print "PrintStack check2:$x| $cindent| $cval \n" if $debug;
	}
	else
	{
	    print"Dump" . Dumper($bottom) if $debug ;
	    die "No value at stackpos $x";
	}
    }
}


sub runCheckDown
{
#	    print "less $lname $name\n";
    my $indent=shift;
    my $lindent=shift;

    my $lpop="";
    my ($cindent,$val,$lpop2) = Peek();
    $val = $val|| "TOP2";
    if (@mystack)
    {
	while ($cindent >= ($lindent-1))
	{
	    $lpop=$val;
	    my $cindent2;
	    my $p	    = Peek();
	    ($cindent2,$val,$lpop2)  = @{$p};
	    if ($cindent2 >= ($lindent-1))
	    {
		my $r = pop @mystack; #,[$indent,$name];
		if ($r)
		{
		    $lpop=$val;
		    ($cindent,$val) = @{$r};

		    my $lastindex=$#mystack;
		    print "popped $cindent|$val;" if $debug;
		    print "look $cindent2" if $debug;
		    print "and check3:$lindent \n" if $debug;
		    print "lastindex:$lastindex\n" if $debug;
		    PrintStack() if $debug;
		    if ($cindent < $lindent)
		    {
			return [$cindent,$val,$lpop];
		    }

		}
		else
		{
		    print"cindent2 $cindent2"  if $debug;
		    print"lindent $lindent"  if $debug;
		    print"cindent $cindent"  if $debug;
		    print"Dump" . Dumper(\@mystack) if $debug;
		    print"Dump" . Dumper($r) if $debug;
		    die  "no value";
		}
	    }
	    else
	    {

		print "Check4:cindent2:$cindent2 " if $debug;
		print "|cindent:$cindent " if $debug;
		print "/ lindent:$lindent " if $debug;
		print "| $lname " if $debug;
		$val = "WTF" unless $val;
		print "|val :$val " if ($val) && $debug;
		print "|lpop :$lpop " if ($val) && $debug;
		print "\n" if $debug;
		PrintStack() if $debug;
		return [$cindent,$val,$lpop];
	    }
	}
	print "less last $lname old $val \n";


    }
    return [$cindent,$val,$lpop];
}

push @mystack,[1,"top"];

my %seen;


our  $apply_subobj= "<xsl:apply-templates select=\"@*\"/>";

sub emitSingle
{
    my $lname=shift;
    if (!$seen{"$lname"}++)
    {
	print "<xsl:template match=\"$lname\">\n";
	print "	<$lname>\n";
	print "         <xsl:call-template name=\"runGenerics\"/>\n";
	print "	</$lname>\n";
	print "</xsl:template>\n";
    }
}

sub emitRule
{
    my $lname=shift || "NONAMEL";
    my $name=shift || "NONAME";

    emitSingle($name);
    emitSingle($lname);

    if ($lname ne $name)
    {
	if (!$seen{"$lname/$name"}++)
	{
	    print "<xsl:template match=\"$lname/$name\">\n";
	    print "	<$lname>\n";
	    print "		<$name>\n";
	    print "                <xsl:call-template name=\"runGenerics\"/>\n";
	    print "		</$name>\n";
	    print "	</$lname>\n";
	    print "</xsl:template>\n";
	}
    }
}

print qq!<?xml version='1.0'?>
<xsl:stylesheet
  xmlns:AST="http://www.phpcompiler.org/phc-1.1"
  xmlns:past="http://www.parrotcode.org/PAST-0.1"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0" >

<xsl:output method='xml' indent='yes' />
<xsl:strip-space  elements="*"/>
!;

while (<>)
{
    if (/^(.+)ELEMENT\s(.+)$/)
    {
	my $indent=length($1);
	my $name=$2;
#	warn "$indent $name\n";

	print "RAWLINE $indent|$_\n" if $debug;

#	next unless /AST/;
	if ($indent > $lindent)
	{
	    emitRule($lname,$name);

	    push @mystack,[$indent,$name];
	}
	elsif($indent eq $lindent)
	{
	    print "same $lname == $name\n" if $debug;
	}
	else
	{
	    my $r=runCheckDown($lindent,$indent);
	    my ($i,$p,$c)=@{$r};
	    emitRule($p,$name);

	    print "check5:". join (",",($i,$p,$c)) . "\n" if $debug;
	}

	$lindent=$indent;
	$lname=$name;

    }
}

print "</xsl:stylesheet>";
